iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
自我挑戰組

轉職AI軟體工程師的自我學習分享筆記系列 第 21

Python 繪圖: 分型樹的繪製 (畫一大堆圖~p.s.還可以for表白用喔!)

  • 分享至 

  • xImage
  •  

前情提要:

經過一連串~ brain storming, debug, paper studying, writing articles, positive of covid... hahaha jk lmao /images/emoticon/emoticon37.gif/images/emoticon/emoticon39.gif

However, I realised that my health is the piority! As a life where you have the energy to focus on everything else you want and dream of.
So, let's have a break for coding some simple python games.

Those games are my first side project, which also my self-study of Python before I start the AI and Big Data program. I learned it from the "小象學堂" which is a wechat account (kinda like wechat python learning robot ?!) that I have given from my brother. (p.s. My siblings were engineer before I be an AI RD/PM... but I'm the only one, who still alive in this field/images/emoticon/emoticon02.gif ... well life is hard... it's another story~ haha LOL, let come back to the article /images/emoticon/emoticon33.gif)

https://ithelp.ithome.com.tw/upload/images/20221001/20151681qbO9vK6PyY.png

分形的介紹 ~

分形理論(Fractal Theory)是當今十分風靡和活躍的新理論、新學科。分形的概念是美籍數學家本華·曼德博(法語:Benoit B. Mandelbrot)首先提出的, 他曾說過說過 "分形是自然界的幾何學"。分形理論的數學基礎是分形幾何學,即由分形幾何衍生出分形信息、分形設計、分形藝術等應用。

分形理論的最基本特點是用分數維度的視角和數學方法描述和研究客觀事物,也就是用分形分維的數學工具來描述研究客觀事物。它跳出了一維的線、二維的面、三維的立體乃至四維時空的傳統藩籬,更加趨近複雜系統的真實屬性與狀態的描述,更加符合客觀事物的多樣性與複雜性。

https://ithelp.ithome.com.tw/upload/images/20221001/20151681yUeuRZfOZK.jpg

繪圖所需的-> "海龜模組" 是什麼?

海龜繪圖很適合用來引導孩子學習編程。最初來自於 Wally Feurzeig, Seymour Papert 和 Cynthia Solomon 於 1967 年所創造的 Logo 編程語言。

Turtle模組是一種簡易繪圖程式,操作方式為載入turtle模組,開啟一個畫布(screen),就能開始控制指標(turtle)移動方向(上、下、左、右)和繪圖應用(下筆、停筆、變換畫筆顏色)等變化應用,所有的控制動作都是使用指令語法操作。

想像一下,一隻機器龜在 x-y 平面上從 (0, 0) 出發。在 import turtle 之後,給它命令 turtle.forward(15) ,然後它就會移動 (在螢幕上!) 15 個單位像素,方向是朝著其正面對的方向。給它命令 turtle.right(25) ,它就會在原地順時針旋轉 25 度。

Turtle模組全名是Turtle graphics,初學Python容易因為名詞而產生困惑,這些名詞都是相同的(Turtle、Turtle graphics、Turtle module、Turtle繪圖、Turtle模組、海龜繪圖)。
https://ithelp.ithome.com.tw/upload/images/20221001/20151681URWeDuiQFJ.jpg

Turtle 和 Screen 的功能如下:

Turtle 方法:

海龜动作

移動和繪製

forward() | fd()
backward() | bk() | back()
right() | rt()
left() | lt()
goto() | setpos() | setposition()
setx()
sety()
setheading() | seth()
home()
circle()
dot()
stamp()
clearstamp()
clearstamps()
undo()
speed()

獲取海龜的狀態

position() | pos()
towards()
xcor()
ycor()
heading()
distance()

設置 & 度量單位

degrees()
radians()

画笔控制

繪圖狀態

pendown() | pd() | down()
penup() | pu() | up()
pensize() | width()
pen()
isdown()

顏色控制

color()
pencolor()
fillcolor()

填充

filling()
begin_fill()
end_fill()

更多繪圖控制

reset()
clear()
write()

海龜狀態

可見性

showturtle() | st()
hideturtle() | ht()
isvisible()

外觀

shape()
resizemode()
shapesize() | turtlesize()
shearfactor()
settiltangle()
tiltangle()
tilt()
shapetransform()
get_shapepoly()

使用事件

onclick()
onrelease()
ondrag()

特殊海龜方法

begin_poly()
end_poly()
get_poly()
clone()
getturtle() | getpen()
getscreen()
setundobuffer()
undobufferentries()

TurtleScreen/Screen 方法

窗口控制

bgcolor()
bgpic()
clearscreen()
resetscreen()
screensize()
setworldcoordinates()

動畫控制

delay()
tracer()
update()

畫面操控

listen()
onkey() | onkeyrelease()
onkeypress()
onclick() | onscreenclick()
ontimer()
mainloop() | done()

設置&特殊方法

mode()
colormode()
getcanvas()
getshapes()
register_shape() | addshape()
turtles()
window_height()
window_width()

输入方法

textinput()
numinput()

Screen 專有方法

bye()
exitonclick()
setup()
title()

本文參考"turtle --- 龜圖學"; 更多詳細烏龜(turtle)function的介紹可以參考此- 連結~

實作完整程式碼(如下):

P.s. Turtle模組在Python程式語言中為內建模組,不須安裝可直接載入使用
程式語法:import turtle

1. 畫一個星星 ~

"""
功能:繪製五角星
"""
import turtle
def main():
    """
    主函數
    """
    #計數器
    count = 1
    while count <= 5:
        turtle.forward(300)
        turtle.right(144)
        count = count + 1
    turtle.exitonclick()

if __name__ == '__main__':
    main()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/201516810Nm6fz2KBC.png

2. 連續向右邊畫很多個星星 ~

"""
功能:繪製五角星
新增功能:加入循環操作繪製重複不同的圖形
"""
import turtle
def draw_pentagram(size):
    """
    繪製五角星
    """
    # #計數器
    count = 1
    while count <= 5:
        turtle.forward(size)
        turtle.right(144)
        # count = count + 1
        count += 1

def main():
    """
    主函數
    """
    turtle.penup()
    turtle.backward(200)
    turtle.pendown()
    turtle.pensize(2)
    turtle.pencolor('red')
    
    size =50
    while size <= 100:
        #調用函數draw_pentagram(size)
        draw_pentagram(size)
        # size = size +10
        size += 10
    turtle.exitonclick()

if __name__ == '__main__':
    main()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20151681PgoGxopwnw.png

3. 畫一棵樹 ~

"""
功能:factual tree 分形樹的繪製
"""
import turtle

def draw_branch(branch_length):
    """
    繪製分形樹
    """
    if branch_length > 5:
        #繪製右側樹枝
        turtle.forward(branch_length)
        print('向前', branch_length)
        turtle.right(20)
        print('右轉20')
        draw_branch(branch_length-15)

        #繪製左側樹枝
        turtle.left(40)
        print('左轉40')
        draw_branch(branch_length-15)

        #返回之前的樹枝
        turtle.right(20)
        print('右轉20')
        turtle.backward(branch_length)
        print('返回向後', branch_length)

def main():
    """
    主函數
    """
    turtle.left(90)
    turtle.penup()
    turtle.backward(150)
    turtle.pendown()
    turtle.color('brown') #can change the colour #etc. green
    turtle.pensize(5)
    draw_branch(100)
    turtle.exitonclick()

if __name__ == '__main__':
    main()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20151681Fr6bEnNJ6y.png
https://ithelp.ithome.com.tw/upload/images/20221001/20151681fzsng1URYA.png
https://ithelp.ithome.com.tw/upload/images/20221001/20151681qbzB7NZi36.png

表白用的python海龜turtle分形樹

(參考此文)

怎在一棵樹上畫樹葉+愛心+喜歡人的名子呢?
我們可以使用turtle()這個函數繪製想要的圖示, 顏色, 粗細, 大小...
而write() 可以填上想要告白對象的名稱~

import turtle
import random
def love(x,y):#在(x,y)處畫愛心lalala
    lv=turtle.Turtle()
    lv.hideturtle()
    lv.up()
    lv.goto(x,y)#定位到(x,y)
    def curvemove():#畫圓弧
        for i in range(20):
            lv.right(10)
            lv.forward(2)
    lv.color('red','pink')
    lv.speed(10000000)
    lv.pensize(1)
    #開始畫愛心 <3
    lv.down()
    lv.begin_fill()
    lv.left(140)
    lv.forward(22)
    curvemove()
    lv.left(120)
    curvemove()
    lv.forward(22)
    lv.write("Jan",font=("Arial",12,"normal"),align="center")#寫上表白的人的名字
    lv.left(140)#畫完復位
    lv.end_fill()

def tree(branchLen,t):
    if branchLen > 5:#剩餘樹枝太少要結束遞迴
        if branchLen<20:#如果樹枝剩餘長度較短則變綠
            t.color("green")
            t.pensize(random.uniform((branchLen + 5) / 4 - 2, (branchLen + 6) / 4 + 5))
            t.down()
            t.forward(branchLen)
            love(t.xcor(),t.ycor())#傳輸現在turtle的座標
            t.up()
            t.backward(branchLen)
            t.color("brown")
            return
        t.pensize(random.uniform((branchLen+5)/4-2,(branchLen+6)/4+5))
        t.down()
        t.forward(branchLen)
        # 以下遞迴
        ang=random.uniform(15,45)
        t.right(ang)
        tree(branchLen-random.uniform(12,16),t)#隨機決定減小長度
        t.left(2*ang)
        tree(branchLen-random.uniform(12,16),t)#隨機決定減小長度
        t.right(ang)
        t.up()
        t.backward(branchLen)

myWin = turtle.Screen()
t = turtle.Turtle()
t.hideturtle()
t.speed(1000)
t.left(90)
t.up()
t.backward(200)
t.down()
t.color("brown")
t.pensize(32)
t.forward(60)
tree(100,t)
myWin.exitonclick()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20151681jLMpy2aNeZ.png

畫一個玫瑰花 ~

畫1個紅色的玫瑰花 + 2片綠色的葉子~
turtle.exitonclick() 可以讓畫完的圖片停在畫面上, 若沒有加這個在最後, 畫完的圖的視窗會自動關閉
完整的程式碼如下:

import turtle
turtle.setup(0.5,0.75)
turtle.fillcolor("red")
turtle.begin_fill()
turtle.left(90)
turtle.penup()
turtle.fd(100)
turtle.pendown()
turtle.right(90)
turtle.circle(6,180)
turtle.circle(20,70)
turtle.seth(305)
turtle.circle(20,150)
turtle.seth(150)
turtle.circle(40,80)
turtle.seth(275)
turtle.fd(23)
print(turtle.pos())
turtle.seth(140)
turtle.fd(5)
turtle.seth(250)
turtle.circle(50,120)
turtle.seth(40)
turtle.circle(65,85)
turtle.seth(240)
turtle.fd(13)
print(turtle.pos())
turtle.seth(110)
turtle.circle(72,17)
turtle.end_fill()
turtle.seth(280)
turtle.fd(37)
turtle.penup()
turtle.goto(25.68,92.90)
turtle.pendown()
turtle.seth(270)
turtle.circle(-100,20)
turtle.circle(60,43)
turtle.penup()
turtle.goto(-31.12,80.21)
turtle.pendown()
turtle.circle(80,40)
turtle.circle(-30,60)
turtle.circle(100,40)
print(turtle.pos())
turtle.circle(-120,25)
print(turtle.pos())
turtle.circle(-200,20)
turtle.penup()
turtle.goto(49.27,-47.94)
turtle.pendown()
turtle.seth(20)
turtle.fd(10)
turtle.begin_fill()
turtle.color("black","green")
turtle.seth(90)
turtle.circle(-30,130)
turtle.seth(260)
turtle.circle(-35,110)
turtle.end_fill()
turtle.seth(12)
turtle.circle(70,37)
turtle.penup()
turtle.goto(75.63,-92.70)
turtle.pendown()
turtle.seth(175)
turtle.fd(10)
turtle.begin_fill()
turtle.color("black","green")
turtle.seth(120)
turtle.circle(25,130)
turtle.seth(310)
turtle.circle(27,110)
turtle.end_fill()
turtle.seth(200)
turtle.circle(-60, 35) # 玫瑰花怎麽試也填充不完全。
turtle.exitonclick()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20151681Soth3ny6yE.png
https://ithelp.ithome.com.tw/upload/images/20221001/20151681Tj4GsyGivt.png

畫樹葉~ (以點的方式)

藍色的點畫成的樹葉~
完整程式碼如下:

from numpy import *
from random import random
import turtle
turtle.reset()
x = array([[.5],[.5]])
p = [0.85,0.92,0.99,1.00]
A1 = array([[.85, 0.04],
            [-0.04,.85]])
b1 = array([[0],[1.6]])
A2 = array([[0.20,-0.26],
            [0.23,0.22]])
b2 = array([[0],[1.6]])
A3 = array([[-0.15,0.28],
            [0.26,0.24]])
b3 = array([[0],[0.44]])

A4 = array([[0,0],
            [0,0.16]])

#含概率的迭代函式系統

turtle.color("blue")
cnt = 1
while True:
    cnt += 1
    if cnt == 2000:
        break
    r = random()
    if r < p[0]:
        x = dot(A1 , x) + b1
    elif r < p[1]:
        x = dot(A2 , x) + b2
    elif r < p[2]:
        x = dot(A3 , x) + b3
    else:
        x = dot(A4 , x)
    #print x[1]
    turtle.up()
    turtle.goto(x[0][0] * 50,x[1][0] * 40 - 240)
    turtle.down()
    turtle.dot()
    turtle.exitonclick()

結果如下:

https://ithelp.ithome.com.tw/upload/images/20221001/20151681xyNDgirinx.png

/images/emoticon/emoticon42.gif
/images/emoticon/emoticon41.gif


上一篇
Python 小遊戲實作: 終極密碼- (猜1個1~100的數字)
下一篇
Python 速算器: 基礎代謝率 (BMR)計算
系列文
轉職AI軟體工程師的自我學習分享筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言